import datetime
from django.shortcuts import render, redirect
from django import forms

from django.conf import settings
from web import models
from utils.pager import Pagination
from utils.bootstrap import BootStrapForm
from django.core.exceptions import ValidationError
import random
from django.db.models import F
from django.conf import settings
from django_redis import get_redis_connection
from django.db import transaction
from django.contrib import messages


def my_order_list(request):
    # 在读取之前页面中设置的message + message删除
    # from django.contrib.messages.api import get_messages
    # messages = get_messages(request)
    # for obj in messages:
    #     print(obj.message)
    # 获取我的订单，当前登录的id
    queryset = models.Order.objects.filter(customer_id=request.nb_user.id, active=1).order_by('-id')
    pager = Pagination(request, queryset)
    return render(request, 'my_order_list.html', {'pager': pager})


class MyOrderModelForm(BootStrapForm, forms.ModelForm):
    class Meta:
        model = models.Order
        fields = ["url", "count"]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        price_count_list = []
        text_count_list = []
        queryset = models.PricePolicy.objects.all().order_by('count')
        for item in queryset:
            unit_price = item.price / item.count
            price_count_list.append([item.count, ">={} ￥{}/条".format(item.count, unit_price), unit_price])
            text_count_list.append(">={} ￥{}/条".format(item.count, unit_price))

        if text_count_list:
            self.fields['count'].help_text = "、".join(text_count_list)
        else:
            self.fields['count'].help_text = '请联系管理员设置价格'

        self.price_count_list = price_count_list

    # 校验最低获取 小于则不通过
    def clean_count(self):
        count = self.cleaned_data['count']
        if not self.price_count_list:
            raise ValidationError('请联系管理员设置价格')
        min_count_limit = self.price_count_list[0][0]

        if count < min_count_limit:
            raise ValidationError('最低支持数量为：{}'.format(min_count_limit))
        return count


def my_order_add(request):
    if request.method == 'GET':
        form = MyOrderModelForm()
        return render(request, 'form.html', {'form': form})
    form = MyOrderModelForm(data=request.POST)
    if not form.is_valid():
        return render(request, 'form.html', {'form': form})

    # 获取 url & count
    video_url = form.cleaned_data['url']
    count = form.cleaned_data['count']

    # 0 获取原播放量
    from utils.video import get_old_view_count
    status, old_view_count = get_old_view_count(video_url)

    if not status:
        form.add_error('url', '视频原来播放获取失败')
        return render(request, 'form.html', {'form': form})
    # 根据数量获取单价 计算出原价
    for idx in range(len(form.price_count_list) - 1, -1, -1):
        limit_count, _, unit_price = form.price_count_list[idx]
        if count >= limit_count:
            break
    total_price = count * unit_price
    # print('总价------------------------------------------》', total_price)

    # 当前的客户所处的级别 计算折扣后的价格
    try:
        with transaction.atomic():
            cus_object = models.Customer.objects.filter(id=request.nb_user.id).select_for_update().first()
            # cus_object.level.percent
            real_price = total_price * cus_object.level.percent / 100
            # 打折 7.5折
            # print(real_price, type(real_price))

            # 判定账户余额是否够
            # print(cus_object.balance, type(cus_object.balance))
            if cus_object.balance < real_price:
                form.add_error('count', '账户余额不足')
                return render(request, 'form.html', {'form': form})
            # 创建订单
            # 生成订单号
            while True:
                rand_number = random.randint(10000000, 99999999)
                ctime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%Sf')
                oid = "{}{}".format(ctime, rand_number)
                exists = models.Order.objects.filter(oid=oid).exists()
                if exists:
                    continue
                break
            # print("订单号", old_view_count)
            # 发送网络请求获取原播放量
            # print('原播放量',  )
            # 客户ID=当前登录客户ID

            form.instance.oid = oid
            form.instance.price = total_price
            form.instance.real_price = real_price
            form.instance.old_view_count = old_view_count
            form.instance.customer_id = request.nb_user.id
            form.save()
            # 账户扣款
            models.Customer.objects.filter(id=request.nb_user.id).update(balance=F('balance') - real_price)
            # cus_object.balance = cus_object.balance - real_price
            # cus_object.save()

            # 生成交易记录
            models.TransactionRecord.objects.create(
                charge_type=3,
                customer_id=request.nb_user.id,
                amount=real_price,
                order_oid=oid
            )
            # except Exception as e:
            # 写入redis队列 (redis启动,django连接redis)
            # 获取redis连接
            conn = get_redis_connection("default")
            # 将订单号放到队列
            conn.lpush(settings.QUEUE_TASK_NAME, oid)
            # team1 = conn.lpush(settings.QUEUE_TASK_NAME, oid)
            # print('存入订单号-------------------------------------------->', team1)
    except Exception as e:
        form.add_error('count', '创建订单失败')
        return render(request, 'form.html', {'form': form})
    return redirect('/my/order/list/')


def my_order_cancel(request, pk):
    #  撤单
    # 撤单成功了
    order_object = models.Order.objects.filter(id=pk, active=1, status=1, customer=request.nb_user.id).first()
    if not order_object:
        messages.add_message(request, settings.MESSAGE_DANGER_TAG, '订单不存在')
        return redirect('/my/order/list/')
    try:
        with transaction.atomic():
            models.Customer.objects.filter(id=request.nb_user.id).select_for_update().first()
            # 1.订单状态变化为 (5, "已撤单")
            models.Order.objects.filter(id=pk,active=1,status=1,customer=request.nb_user.id).update(status=5)

            #2.归还余额
            models.Customer.objects.filter(id=request.nb_user.id).update(balance=F('balance') + order_object.real_price)
            #3.交易记录
            models.TransactionRecord.objects.create(
                charge_type=5,
                customer_id=request.nb_user.id,
                amount=order_object.real_price,
                order_oid=order_object.oid
            )
            messages.add_message(request, messages.SUCCESS, '撤单成功')
            return redirect('/my/order/list/')
    except Exception as e:
        messages.add_message(request, settings.MESSAGE_DANGER_TAG, "撤单失败{}".format(str(e)))
        return redirect('/my/order/list/')
